package org.cheetah.core.action.impl;

import java.util.Collection;

import org.cheetah.core.action.Action;
import org.cheetah.core.action.ActionPipeline;
import org.cheetah.core.exchange.Exchange;

public class DefaultActionPipeline implements ActionPipeline {
	private DefaultActionContext head;

	private DefaultActionContext tail;

	public DefaultActionPipeline() {
		this.head = null;
		this.tail = null;
	}

	public DefaultActionPipeline(Action... actions) {
		this();

		for (Action action : actions) {
			addLast(action);
		}
	}

	public DefaultActionPipeline(Collection<? extends Action> actions) {
		this();

		for (Action action : actions) {
			addLast(action);
		}
	}

	private DefaultActionContext getContext(Action action) {
		DefaultActionContext current = head;

		while (current != null) {
			if (current.getAction().equals(action)) {
				break;
			}
			current = current.next;
		}

		return current;
	}

	public void process(Exchange exchange) throws Exception {
		if (head != null) {
			head.getAction().process(head, exchange);
		}
	}

	public void addLast(Action action) {
		DefaultActionContext ctx = new DefaultActionContext(action);
		if (tail == null) {
			head = ctx;
			tail = ctx;
		} else {
			tail.next = ctx;
			ctx.prev = tail;

			tail = ctx;
		}
	}

	public void remove(Action action) {
		DefaultActionContext ctx = getContext(action);
		if (ctx != null) {
			if ((head == ctx) && (tail == ctx)) {
				head = null;
				tail = null;
			} else if (head == ctx) {
				head = head.next;

				ctx.next = null;
				head.prev = null;
			} else if (tail == ctx) {
				tail = tail.prev;

				ctx.prev = null;
				tail.next = null;
			} else {
				ctx.prev.next = ctx.next;
				ctx.next.prev = ctx.prev;

				ctx.prev = null;
				ctx.next = null;
			}
		}
	}
}
